package com.zyndev.sanchi.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;

import static com.zyndev.sanchi.util.StringUtil.matches;

public class JavaDocUtil {

    public static List<ClassCommentInfo> extractJavaDoc(Class clazz, String sourcePath) throws IOException {
        String pattern = "/\\*\\*([\\s\\S]*?)\\*/|class [A-Za-z0-9]+|public [A-Za-z0-9]+ [A-Za-z]+";
        System.out.println("开始处理：" + clazz.getName() + "\n-----------------------------------------------");
        String filePath = clazz.getName().replace(".", "/");
        File f = new File(sourcePath + filePath + ".java");
        BufferedReader reader = new BufferedReader(new FileReader(f));
        StringBuilder sb = new StringBuilder(1000);
        String line = reader.readLine();
        while (line != null) {
            sb.append(line).append("\n");
            line = reader.readLine();
        }
        String author = null;
        reader.close();
        List<String> results = matches(sb.toString(), pattern);

        ClassCommentInfo classCommentInfo = new ClassCommentInfo();
        List<ClassCommentInfo> classCommentInfoList = new ArrayList<>();

        // 判断出 public class xxx 的位置，找出类注释
        int classIndex = Integer.MAX_VALUE;
        for (int index = 0; index < results.size(); ++index) {
            if (results.get(index).startsWith("/**")) {
                if (index > classIndex) {
                    classCommentInfo.setComment(results.get(index));
                    List<String> paramList = matches(results.get(index), "@param([\\s\\S]*?)\\*");
                    Map<String, MethodParamInfo> methodParamInfoMap = new HashMap<>(paramList.size());

                    for (String param : paramList) {
                        String paramComment = param.replace("\n", "").replace("*", "");
                        String[] paramComments = paramComment.split("\\s");
                        MethodParamInfo methodParamInfo = new MethodParamInfo();
                        methodParamInfo.setName(paramComments[1]);
                        methodParamInfo.setComment(paramComment.replaceFirst(paramComments[0], "").replaceFirst(paramComments[1], "").trim());
                        methodParamInfoMap.put(methodParamInfo.getName(), methodParamInfo);
                    }
                    classCommentInfo.setMethodParamInfoMap(methodParamInfoMap);
                }
            } else {
                if (results.get(index).contains("class")) {
                    classIndex = index;
                    if (index > 0) {
                        List<String> paramList = matches(results.get(index - 1), "@author([\\s\\S]*?)\\*");
                        if (!paramList.isEmpty()) {
                            String paramComment = paramList.get(0).replace("\n", "").replace("*", "");
                            String[] paramComments = paramComment.split("\\s");
                            author = String.join(" ", Arrays.asList(paramComments).subList(1, paramComments.length));
                        }
                    }
                    classCommentInfo.setType(0);
                } else {
                    classCommentInfo.setType(1);
                }
                String[] array = results.get(index).split("\\s");
                classCommentInfo.setName(array[array.length - 1]);
                classCommentInfo.setAuthor(author);
                classCommentInfoList.add(classCommentInfo);
                classCommentInfo = new ClassCommentInfo();
            }
        }
        return classCommentInfoList;
    }

}
